package
{
	public class ObjectManager
	{
		public var objList:Object;
		public var objArray:Array;
		public var numObjs:Number;
		public var nextID:Number;
		public var gridList:Object;
		public var gridNum:Number;
		public var updateList:Object;
		public var updateNum:Number;
		public var drawList:Object;
		public var drawNum:Number;
		public var thinkList:Object;
		public var thinkNum:Number;
		public var curThinker = null;
		public var thinkRate:Number;
		public var thinkTimer:Number;

		public function ObjectManager()
		{
			this.InitDataStructs();
		}

		public function InitDataStructs():void
		{
			this.objList = new Object();
			this.objArray = new Array();
			this.numObjs = 0;
			this.nextID = 0;
			this.gridList = new Object();
			this.gridNum = 0;
			this.updateList = new Object();
			this.updateNum = 0;
			this.drawList = new Object();
			this.drawNum = 0;
			this.thinkList = new Object();
			this.thinkNum = 0;
			this.curThinker = null;
			this.thinkRate = 8;
			this.thinkTimer = 0;
		}

		public function Register(obj):void
		{
			var _local1 = obj;
			_local1.UID = this.nextID++;
			this.objList[_local1.UID] = _local1;
			this.objArray.push(_local1);
			this.numObjs++;
		}

		public function AddToGrid(obj):void
		{
			var _local1 = obj;
			_local1.cell = Main.getInstance().tiles.GetTile_V(_local1.pos);
			_local1.cell.InsertObj(_local1);
			this.gridList[_local1.UID] = _local1;
			this.gridNum++;
		}

		public function RemoveFromGrid(obj):void
		{
			var _local1 = obj;
			if (this.gridList[_local1.UID] != null)
			{
				_local1.cell.RemoveObj(_local1);
				delete this.gridList[_local1.UID];
				this.gridNum--;
				return;
			}
		}

		public function Moved(obj):Boolean
		{
			var _local1 = obj;
			var _local2 = _local1.cell;
			var n = Main.getInstance().tiles.GetTile_V(_local1.pos);
			if (_local2 != n)
			{
				_local2.RemoveObj(_local1);
				_local1.cell = n;
				n.InsertObj(_local1);
				return(true);
			}
			return(false);
		}

		public function GetObj(ID)
		{
			var _local1 = ID;
			var _local2 = this.objList[_local1];
			if (_local2 == null)
			{
			}
			else
			{
				return(this.objList[_local1]);
			}
			return(undefined);
		}

		public function GetObjType(obj)
		{
			return obj.OBJ_TYPE;
		}

		public function IdleObjectsAfterDeath():void
		{
			for (var _local2 in this.objList)
			{
				this.objList[_local2].IdleAfterDeath();
			}
		}

		public function DumpThinkList():String
		{
			var _local3 = "THINK LIST:\n";
			var head = this.curThinker;
			var startID = head.UID;
			_local3 = _local3 + ("head: " + startID);
			_local3 = _local3 + ((((("\n" + head.prevThinker.UID) + "<-") + startID) + "->") + head.nextThinker.UID);
			if (this.thinkNum == 0)
			{
				_local3 = _local3 + "no thinkers!";
				return(_local3);
			}
			var _local2 = "   ";
			var _local1 = head.nextThinker;
			while (_local1.UID != startID)
			{
				_local3 = _local3 + (((((("\n" + _local2) + _local1.prevThinker.UID) + "<-") + _local1.UID) + "->") + _local1.nextThinker.UID);
				_local1 = _local1.nextThinker;
				_local2 = _local2 + "   ";
			}
			return(_local3);
			return(_local3);
		}

		public function Tick():void
		{
			if (0 < this.updateNum)
			{
				for (var _local2 in this.updateList)
				{
					this.updateList[_local2].Update();
				}
			}
			if (0 < this.thinkNum)
			{
				if (this.thinkRate < this.thinkTimer)
				{
					this.thinkTimer = 0;
					this.curThinker.Think();
					this.curThinker = this.curThinker.nextThinker;
				}
				else
				{
					this.thinkTimer++;
				}
			}
		}

		public function StartUpdate(obj):void
		{
			var _local1 = obj;
			if (this.updateList[_local1.UID] == null)
			{
				this.updateList[_local1.UID] = _local1;
				this.updateNum++;
			}
		}

		public function EndUpdate(obj):void
		{
			if (this.updateList[obj.UID] == null)
			{
			}
			else
			{
				delete this.updateList[obj.UID];
				this.updateNum--;
			}
		}

		public function StartDraw(obj):void
		{
			var _local1 = obj;
			if (this.drawList[_local1.UID] == null)
			{
				this.drawList[_local1.UID] = _local1;
				this.drawNum++;
			}
		}

		public function EndDraw(obj):void
		{
			if (this.drawList[obj.UID] == null)
			{
			}
			else
			{
				delete this.drawList[obj.UID];
				this.drawNum--;
			}
		}

		public function StartThink(obj):void
		{
			var _local1 = obj;
			if (this.thinkList[_local1.UID] == null)
			{
				this.thinkList[_local1.UID] = _local1;
				this.thinkNum++;
				if (this.thinkNum == 1)
				{
					this.curThinker = _local1;
					_local1.nextThinker = _local1;
					_local1.prevThinker = _local1;
				}
				else
				{
					_local1.nextThinker = this.curThinker;
					_local1.prevThinker = this.curThinker.prevThinker;
					_local1.prevThinker.nextThinker = _local1;
					_local1.nextThinker.prevThinker = _local1;
					this.curThinker = _local1;
				}
			}
		}

		public function EndThink(obj):void
		{
			var _local1 = obj;
			if (this.thinkList[_local1.UID] == null)
			{
			}
			else
			{
				delete this.thinkList[_local1.UID];
				this.thinkNum--;
				if (this.thinkNum <= 0)
				{
					_local1.nextThinker = null;
					_local1.prevThinker = null;
					this.curThinker = null;
					this.thinkNum = 0;
				}
				else
				{
					_local1.nextThinker.prevThinker = _local1.prevThinker;
					_local1.prevThinker.nextThinker = _local1.nextThinker;
					if (_local1 == this.curThinker)
					{
						this.curThinker = _local1.nextThinker;
					}
					_local1.nextThinker = null;
					_local1.prevThinker = null;
				}
			}
		}

		public function Clear():void
		{
			for (var _local2 in this.thinkList)
			{
				this.EndThink(this.thinkList[_local2]);
			}
			for (var _local2 in this.gridList)
			{
				this.RemoveFromGrid(this.gridList[_local2]);
			}
			for (var _local2 in this.updateList)
			{
				this.EndUpdate(this.updateList[_local2]);
			}
			for (var _local2 in this.drawList)
			{
				this.EndDraw(this.drawList[_local2]);
			}
			for (var _local2 in this.objArray)
			{
				delete this.objArray[_local2];
			}
			for (var _local2 in this.objList)
			{
				this.objList[_local2].next = null;
				this.objList[_local2].prev = null;
				this.objList[_local2].nextThinker = null;
				this.objList[_local2].prevThinker = null;
				this.objList[_local2].UnInit();
				this.objList[_local2].Destruct();
				delete this.objList[_local2];
			}
			Main.getInstance().tiles.ClearGrid();
			this.objList = null;
			this.objArray = null;
			this.updateList = null;
			this.drawList = null;
			this.gridList = null;
			this.thinkList = null;
			this.curThinker = null;
			this.InitDataStructs();
		}

		public function Draw():void
		{
			for (var _local2 in this.drawList)
			{
				this.drawList[_local2].Draw();
			}
		}

		//
		public static const OBJTYPE_GOLD:int = 0;
		public static const OBJTYPE_BOUNCEBLOCK:int = 1;
		public static const OBJTYPE_LAUNCHPAD:int = 2;
		public static const OBJTYPE_TURRET:int = 3;
		public static const OBJTYPE_FLOORGUARD:int = 4;
		public static const OBJTYPE_PLAYER:int = 5;
		public static const OBJTYPE_DRONE:int = 6;
		public static const OBJTYPE_ONEWAYPLATFORM:int = 7;
		public static const OBJTYPE_THWOMP:int = 8;
		public static const OBJTYPE_TESTDOOR:int = 9;
		public static const OBJTYPE_HOMINGLAUNCHER:int = 10;
		public static const OBJTYPE_EXIT:int = 11;
		public static const OBJTYPE_MINE:int = 12;

		public function GetObjectStates():String
		{
			var _local2 = "";
			var _local1 = 0;
			while (_local1 < this.objArray.length)
			{
				_local2 = _local2 + this.objArray[_local1].OBJ_TYPE;
				_local2 = _local2 + NinjaGame.OBJTYPE_SEPERATION_CHAR;
				_local2 = _local2 + this.objArray[_local1].DumpInitData();
				_local2 = _local2 + NinjaGame.OBJECT_SEPERATION_CHAR;
				_local1++;
			}
			if (0 < _local2.length)
			{
				var lastD = _local2.lastIndexOf(NinjaGame.OBJECT_SEPERATION_CHAR);
				_local2 = _local2.substring(0, lastD);
			}
			return(_local2);
		}

		public function SpawnGameObject(OBJ_TYPE, params)
		{
			var _local2 = OBJ_TYPE;
			var _local1 = this.BuildObject(_local2);
			_local1.OBJ_TYPE = _local2;
			_local1.Init(params);
			return(_local1.UID);
			return(_local2);
		}

		public function BuildObject(OBJ_TYPE)
		{
			var _local1 = OBJ_TYPE;
			if (_local1 == ObjectManager.OBJTYPE_PLAYER)
			{
				var _local2 = new PlayerObject();
				return(_local2);
			}
			else if (_local1 == ObjectManager.OBJTYPE_GOLD)
			{
				var _local2 = new GoldObject();
				return(_local2);
			}
			else if (_local1 == ObjectManager.OBJTYPE_BOUNCEBLOCK)
			{
				var _local2 = new BounceBlockObject();
				return(_local2);
			}
			else if (_local1 == ObjectManager.OBJTYPE_LAUNCHPAD)
			{
				var _local2 = new LaunchPadObject();
				return(_local2);
			}
			else if (_local1 == ObjectManager.OBJTYPE_TURRET)
			{
				var _local2 = new TurretObject();
				return(_local2);
			}
			else if (_local1 == ObjectManager.OBJTYPE_FLOORGUARD)
			{
				var _local2 = new FloorGuardObject();
				return(_local2);
			}
			else if (_local1 == ObjectManager.OBJTYPE_DRONE)
			{
				var _local2 = new DroneObject();
				return(_local2);
			}
			else if (_local1 == ObjectManager.OBJTYPE_ONEWAYPLATFORM)
			{
				var _local2 = new OneWayPlatformObject();
				return(_local2);
			}
			else if (_local1 == ObjectManager.OBJTYPE_THWOMP)
			{
				var _local2 = new ThwompObject();
				return(_local2);
			}
			else if (_local1 == ObjectManager.OBJTYPE_TESTDOOR)
			{
				var _local2 = new TestDoorObject();
				return(_local2);
			}
			else if (_local1 == ObjectManager.OBJTYPE_HOMINGLAUNCHER)
			{
				var _local2 = new HomingLauncherObject();
				return(_local2);
			}
			else if (_local1 == ObjectManager.OBJTYPE_EXIT)
			{
				var _local2 = new ExitObject();
				return(_local2);
			}
			else if (_local1 == ObjectManager.OBJTYPE_MINE)
			{
				var _local2 = new MineObject();
				return(_local2);
				return(undefined);
			}
			return(undefined);
		}
	}
}